package vworld;

import generated.business.admin.AdminService;
import generated.business.admin.AdminServiceHelper;
import generated.business.avatar.AvatarService;
import generated.business.avatar.AvatarServiceHelper;
import generated.business.connection.ConnectionService;
import generated.business.connection.ConnectionServiceHelper;
import generated.business.message.MessageService;
import generated.business.message.MessageServiceHelper;
import generated.business.room.RoomService;
import generated.business.room.RoomServiceHelper;
import generated.business.user.UserService;
import generated.business.user.UserServiceHelper;
import generated.business.world.WorldService;
import generated.business.world.WorldServiceHelper;
import generated.callback.ClientCallback;
import generated.callback.ClientCallbackHelper;
import generated.domain.room.Room;
import generated.domain.user.User;
import generated.domain.world.World;
import gui.Activator;

import java.util.Properties;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.swt.widgets.Display;
import org.omg.CORBA.ORB;
import org.omg.CORBA.ORBPackage.InvalidName;
import org.omg.CosNaming.NamingContextExt;
import org.omg.CosNaming.NamingContextExtHelper;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.POAHelper;
import org.omg.PortableServer.POAManagerPackage.AdapterInactive;

import vworld.callback.ClientCallbackServant;

public class Client {
	public static ORB ORB = null;
	public static NamingContextExt NAMING_CONTEXT_REF = null;
	public static POA ROOT_POA = null;

	public static AdminService ADMIN_SERVICE = null;
	public static AvatarService AVATAR_SERVICE = null;
	public static ConnectionService CONNECTION_SERVICE = null;
	public static MessageService MESSAGE_SERVICE = null;
	public static RoomService ROOM_SERVICE = null;
	public static UserService USER_SERVICE = null;
	public static WorldService WORLD_SERVICE = null;

	public static User CONNECTED_USER = null;
	public static World CURRENT_WORLD = null;
	public static Room CURRENT_ROOM = null;

	public static ClientCallback CALL_BACK_REF = null;

	public static boolean initORB(String host, String port) {
		Properties props = new Properties();
		// create and initialize the ORB
		if (!host.equals("") && !port.equals("")) {
			props.put("org.omg.CORBA.ORBInitialPort", port);
			props.put("org.omg.CORBA.ORBInitialHost", host);
		}

		String[] args = new String[0];
		ORB = ORB.init(args, props);
		System.out.println("Client : Initialized ORB");

		try {
			ROOT_POA = POAHelper.narrow(ORB
					.resolve_initial_references("RootPOA"));
			ROOT_POA.the_POAManager().activate();
			// get the root naming context
			org.omg.CORBA.Object objRef = ORB
					.resolve_initial_references("NameService");
			System.out.println("Client : Resolved NameService");
			NAMING_CONTEXT_REF = NamingContextExtHelper.narrow(objRef);

			initAdminService();
			initAvatarService();
			initConnectionService();
			initMessageService();
			initRoomService();
			initUserService();
			initWorldService();
			return true;
		} catch (AdapterInactive e) {
			e.printStackTrace();
		} catch (InvalidName e) {
			e.printStackTrace();
		}
		return false;
	}

	public static void initAdminService() {
		try {
			// resolve the Object Reference in Naming
			ADMIN_SERVICE = AdminServiceHelper.narrow(NAMING_CONTEXT_REF
					.resolve_str("AdminService"));

		} catch (Exception exception) {
			System.out.println("ERROR : " + exception);
			exception.printStackTrace(System.out);
		}
	}

	public static void initAvatarService() {
		try {
			// resolve the Object Reference in Naming
			AVATAR_SERVICE = AvatarServiceHelper.narrow(NAMING_CONTEXT_REF
					.resolve_str("AvatarService"));

		} catch (Exception exception) {
			System.out.println("ERROR : " + exception);
			exception.printStackTrace(System.out);
		}
	}

	public static void initConnectionService() {
		try {
			// resolve the Object Reference in Naming
			CONNECTION_SERVICE = ConnectionServiceHelper
					.narrow(NAMING_CONTEXT_REF.resolve_str("ConnectionService"));

		} catch (Exception exception) {
			System.out.println("ERROR : " + exception);
			exception.printStackTrace(System.out);
		}
	}

	public static void initMessageService() {
		try {
			// resolve the Object Reference in Naming
			MESSAGE_SERVICE = MessageServiceHelper.narrow(NAMING_CONTEXT_REF
					.resolve_str("MessageService"));

		} catch (Exception exception) {
			System.out.println("ERROR : " + exception);
			exception.printStackTrace(System.out);
		}
	}

	public static void initRoomService() {
		try {
			// resolve the Object Reference in Naming
			ROOM_SERVICE = RoomServiceHelper.narrow(NAMING_CONTEXT_REF
					.resolve_str("RoomService"));

		} catch (Exception exception) {
			System.out.println("ERROR : " + exception);
			exception.printStackTrace(System.out);
		}
	}

	public static void initUserService() {
		try {
			// resolve the Object Reference in Naming
			USER_SERVICE = UserServiceHelper.narrow(NAMING_CONTEXT_REF
					.resolve_str("UserService"));

		} catch (Exception exception) {
			System.out.println("ERROR : " + exception);
			exception.printStackTrace(System.out);
		}
	}

	public static void initWorldService() {
		try {
			// resolve the Object Reference in Naming
			WORLD_SERVICE = WorldServiceHelper.narrow(NAMING_CONTEXT_REF
					.resolve_str("WorldService"));

		} catch (Exception exception) {
			System.out.println("ERROR : " + exception);
			exception.printStackTrace(System.out);
		}
	}

	public static void registerClientCallbackServant() {
		// create clientRoom callback servant and register it with the ORB
		ClientCallbackServant clientCallbackImpl = new ClientCallbackServant();
		clientCallbackImpl.setORB(ORB);
		clientCallbackImpl.userLogin(CONNECTED_USER.login);
		clientCallbackImpl.userRole(CONNECTED_USER.role);
		clientCallbackImpl.avatarName(CONNECTED_USER.avatar.name);
		clientCallbackImpl.roomName("");

		org.omg.CORBA.Object ref = null;
		try {
			ref = ROOT_POA.servant_to_reference(clientCallbackImpl);
		} catch (Exception e) {
			IStatus errorStatus = new Status(IStatus.ERROR,
					Activator.PLUGIN_ID, 0, e.getMessage(), e);
			ErrorDialog.openError(Display.getCurrent().getActiveShell(),
					"Can not register client callback",
					"Error in registering client callback", errorStatus);
			e.printStackTrace();
		}
		CALL_BACK_REF = ClientCallbackHelper.narrow(ref);
	}
}